/**
 * Copyright 2011 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.google.api.adwords.starterkit.db.structures;

import org.apache.commons.lang.ArrayUtils;
import org.apache.log4j.Logger;

import com.google.api.adwords.v201101.cm.BiddingStrategy;
import com.google.api.adwords.v201101.cm.BudgetBudgetDeliveryMethod;
import com.google.api.adwords.v201101.cm.BudgetBudgetPeriod;
import com.google.api.adwords.v201101.cm.CampaignStatus;

import com.google.api.adwords.starterkit.utils.Utils;

/**
 * The Class CampaignStructure contains all AdWords Campaigns fields managed by 
 * this framework.
 * 
 * @author rodrigo.f.vale@gmail.com  (Rodrigo Vale)
 */
public class CampaignStructure {
  private int localId;
  private long campaignId;
  private long budgetAmount;
  private String endDate;
  private String startDate;
  private CampaignStatus status;
  private String name = null;
  private boolean isStatusModifiable = true;
  private boolean isBudgetModifiable = true;
  private boolean isEndDateModifiable = true;
  private BudgetBudgetPeriod budgetPeriod;
  private BudgetBudgetDeliveryMethod deliveryMethod;
  private float ctr;
  private long clicks;
  private float cost;
  private long impressions;
  private long conversions;
  private long transactions;
  private boolean isStatsAvailable;
  private boolean isLanguageModified; 
  private boolean isNetworkModified;
  private boolean isGeoModified;
  private boolean isBiddingModified;
  private boolean isPlatformModified;
  private boolean isBanned;
  private String biddingStrategy;
  private String pricingModel;
  private long bidCeiling;
  private String oldBiddingStrategy;
  private boolean isBidModified;
  private static final Logger log = Logger.getLogger("StarterKit");
  
  public void setLocalId(int localId) {
    this.localId = localId;
  }
  
  public int getLocalId() {
    return localId;
  }
  
  public void setCampaignId(long campaignId) {
    this.campaignId = campaignId;
  }
  
  public long getCampaignId() {
    return campaignId;
  }

  public void setBudgetAmount(long budgetAmount) {
    this.budgetAmount = budgetAmount;
  }

  public long getBudgetAmount() {
    return budgetAmount;
  }

  public void setEndDate(String endDate) {
    this.endDate = endDate;
  }

  public String getEndDate() {
    return endDate;
  }

  public void setStartDate(String startDate) {
    this.startDate = startDate;
  }

  public String getStartDate() {
    return startDate;
  }

  public void setStatus(CampaignStatus status) {
    this.status = status;
  }

  public void setStatus(String status) {
    status = status.toUpperCase();
    CampaignStructure.validateStatus(status);
    this.status = CampaignStatus.fromString(status);
  }

  public CampaignStatus getStatus() {
    return status;
  }

  public void setName(String name) {
    this.name = name;
  }

  public String getName() {
    return name;
  }

  public void setStatusModifiable(boolean canModifyStatus) {
    this.isStatusModifiable = canModifyStatus;
  }

  public boolean isStatusModifiable() {
    return isStatusModifiable;
  }

  public void setBudgetModifiable(boolean canModifyBudget) {
    this.isBudgetModifiable = canModifyBudget;
  }

  public boolean isBudgetModifiable() {
    return isBudgetModifiable;
  }

  public void setEndDateModifiable(boolean isEndDateModifiable) {
    this.isEndDateModifiable = isEndDateModifiable;
  }

  public boolean isEndDateModifiable() {
    return isEndDateModifiable;
  }

  public void setBudgetPeriod(String budgetPeriod) {
    budgetPeriod = budgetPeriod.toUpperCase();
    CampaignStructure.validateBudgetPeriod(budgetPeriod);
    this.budgetPeriod = BudgetBudgetPeriod.fromString(budgetPeriod);
  }

  public void setBudgetPeriod(BudgetBudgetPeriod budgetPeriod) {
    this.budgetPeriod = budgetPeriod;
  }

  public BudgetBudgetPeriod getBudgetPeriod() {
    return budgetPeriod;
  }

  public void setDeliveryMethod(String deliveryMethod) {
    deliveryMethod = deliveryMethod.toUpperCase();
    CampaignStructure.validateDeliveryMethod(deliveryMethod);
    this.deliveryMethod = BudgetBudgetDeliveryMethod.fromString(deliveryMethod);
  }
  
  public void setDeliveryMethod(BudgetBudgetDeliveryMethod deliveryMethod) {
    this.deliveryMethod = deliveryMethod;
  }

  public BudgetBudgetDeliveryMethod getDeliveryMethod() {
    return deliveryMethod;
  }

  public void setCtr(float ctr) {
    this.ctr = ctr;
  }

  public float getCtr() {
    return ctr;
  }

  public void setClicks(long clicks) {
    this.clicks = clicks;
  }

  public long getClicks() {
    return clicks;
  }

  public void setCost(float cost) {
    this.cost = cost;
  }

  public float getCost() {
    return cost;
  }

  public void setImpressions(long impressions) {
    this.impressions = impressions;
  }

  public long getImpressions() {
    return impressions;
  }

  public void setConversions(long conversions) {
    this.conversions = conversions;
  }

  public long getConversions() {
    return conversions;
  }

  public void setTransactions(long transactions) {
    this.transactions = transactions;
  }

  public long getTransactions() {
    return transactions;
  }

  public void setStatsAvailable(boolean isStatsAvailable) {
    this.isStatsAvailable = isStatsAvailable;
  }

  public boolean isStatsAvailable() {
    return isStatsAvailable;
  }

  public void setLanguageModified(boolean isLanguageModified) {
    this.isLanguageModified = isLanguageModified;
  }

  public boolean isLanguageModified() {
    return isLanguageModified;
  }

  public void setNetworkModified(boolean isNetworkModified) {
    this.isNetworkModified = isNetworkModified;
  }

  public boolean isModifiedNetwork() {
    return isNetworkModified;
  }

  public void setGeoModified(boolean isGeoModified) {
    this.isGeoModified = isGeoModified;
  }

  public boolean isModifiedGeo() {
    return isGeoModified;
  }

  public void setBiddingModified(boolean isBiddingModified) {
    this.isBiddingModified = isBiddingModified;
  }

  public boolean isBiddingModified() {
    return isBiddingModified;
  }

  public void setPlatformModified(boolean isPlatformModified) {
    this.isPlatformModified = isPlatformModified;
  }

  public boolean isPlatformModified() {
    return isPlatformModified;
  }

  public void setBanned(boolean banned) {
    this.isBanned = banned;
  }

  public boolean isBanned() {
    return isBanned;
  }

  public void setBiddingStrategy(String biddingStrategy) {
    biddingStrategy = biddingStrategy.toUpperCase();
    CampaignStructure.validateBiddingStrategy(biddingStrategy);
    this.biddingStrategy = biddingStrategy;
  }

  public String getBiddingStrategy() {
    return biddingStrategy;
  }
  
  public void setPricingModel(String pricingModel) {
    pricingModel = pricingModel.toUpperCase();
    CampaignStructure.validatePricingModel(pricingModel);
    this.pricingModel = pricingModel;
  }

  public String getPricingModel() {
    return pricingModel;
  }

  public void setBidCeiling(long bidCeiling) {
    this.bidCeiling = bidCeiling;
  }

  public long getBidCeiling() {
    return bidCeiling;
  }

  public void setOldBiddingStrategy(String oldBiddingStrategy) {
    this.oldBiddingStrategy = oldBiddingStrategy;
  }

  public String getOldBiddingStrategy() {
    return oldBiddingStrategy;
  }

  public void setBidModified(boolean isBidModified) {
    this.isBidModified = isBidModified;
  }

  public boolean isBidModified() {
    return isBidModified;
  }

  public static boolean validateStatus(String status) {
    String valids[] = {"ACTIVE", "DELETED", "PAUSED"};
    if (!ArrayUtils.contains(valids, status)) {
      log.error("Wrong campaign status: " + status);
      log.error("Valids status are: " + Utils.toString(valids));
      throw new RuntimeException();
    }
    return true;
  }
  
  public static boolean validateBudgetPeriod(String budgetPeriod) {
    String valids[] = {"DAILY", "MONTHLY"};
    if (!ArrayUtils.contains(valids, budgetPeriod)) {
      log.error("Wrong campaign budgetPeriod:" + budgetPeriod);
      log.error("Valids budgetPeriod are: " + Utils.toString(valids));
      throw new RuntimeException();
    }
    return true;
  }
  
  public static boolean validateDeliveryMethod(String deliveryMethod) {
    String valids[] = {"STANDARD", "ACCELERATED"};
    if (!ArrayUtils.contains(valids, deliveryMethod)) {
      log.error("Wrong campaign deliveryMethod:" + deliveryMethod);
      log.error("Valids deliveryMethod are: " + Utils.toString(valids));
      throw new RuntimeException();
    }
    return true;
  }
  
  public static boolean validateBiddingStrategy(String biddingStrategy) {
    String valids[] = {"BUDGETOPTIMIZER","CONVERSIONOPTIMIZER","MANUALCPC","MANUALCPM","PERCENTCPA"};
    if (!ArrayUtils.contains(valids, biddingStrategy)) {
      log.error("Wrong campaign biddingStrategy:" + biddingStrategy);
      log.error("Valids biddingStrategy are: " + Utils.toString(valids));
      throw new RuntimeException();
    }
    return true;
  }
  
  public static boolean validatePricingModel(String pricingModel) {
    String valids[] = {"CLICKS", "IMPRESSIONS", "CONVERSIONS", ""};
    if (!ArrayUtils.contains(valids, pricingModel)) {
      log.error("Wrong campaign pricingModel:" + pricingModel);
      log.error("Valids pricingModel are: " + Utils.toString(valids));
      throw new RuntimeException();
    }
    return true;    
  }
  
}
